﻿#ifndef RXTREE_H
#define RXTREE_H

#include "RXEntitySystem_global.h"

#include <ReflectableObject.h>

class RXEntitySystem_EXPORT RXTree :public ReflectableObject
{
public:
	REFLECTABLE(RXTree, ReflectableObject);
public:
	RXTree();
	~RXTree();

	std::vector<RXTree*> GetChildren();

	template<typename T>
	T* FindChild(const std::wstring& name, bool isRecursive) const{
		std::vector<RXTree*> temp;
        FindChildImp(T::staticMetaInfo(), name, false, isRecursive, temp);

		if (temp.empty()) {
			return NULL;
		}

		return dynamic_cast<T*>(temp[0]);
	}

	template<typename T>
	std::vector<T*> FindChildren(const std::wstring& name, bool isRecursive) const{
		std::vector<RXTree*> temp;
		FindChildImp(T::staticMetaInfo(), name, true, isRecursive, temp);

		std::vector<T*> ret;

		for (auto i : temp) {
			ret.push_back(dynamic_cast<T*>(i));
		}

		return ret;
	}

	virtual void SetParent(RXTree* child);
	RXTree* GetParent() const;

	bool IsAncestorOf(RXTree* child);

	std::wstring GetName() const;
	void SetName(std::wstring name);

public:
	Signal<> ParentChanged;

private:
	void FindChildImp(const MetaInfo& meta, const std::wstring& name, bool isAll, bool isRecursive, std::vector<RXTree*>& ret) const;
	void swapParent(RXTree* p);
private:
	std::set<RXTree*> m_children;
	RXTree* m_parent;
	std::wstring m_name;
};

#endif // !RXTREE_H
